package com.cndongtai.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;

import com.cndongtai.util.ByteUtil;

public class SocketHandler implements Runnable{

	private Socket socket;
	
	public SocketHandler(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		try {
			System.out.println("有连接进入");
			InputStream in=socket.getInputStream();
			OutputStream out=socket.getOutputStream();
		
			// 获取签到报文
			byte[] buf=new byte[1024];
			
			int length=in.read(buf);
			
			StringBuffer sb = new StringBuffer();
			for(int i=0;i<length;i++) {
				sb.append(ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[i])).toUpperCase())).append(" ");
			}
			
			System.out.println(new Date() + "req===>" + sb.toString());
			//A2 5B 00 10 48 A1 00 00 00 01 11 11 00 00 82 B5
			
			// 判断报文头
			if(length<10) {
				System.out.println("报文不合法1");
				return;
			}
			
			// 校验报文头
			String header = ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[0])).toUpperCase()) + ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[1])).toUpperCase());
			if(!"A25B".equals(header)) {
				System.out.println("报文不合法2");
				return;
			}
			
			// 获取长度
			int msgsize = Integer.parseInt(ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[2])).toUpperCase()) + ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[3])).toUpperCase()), 16);
			System.out.println(length+"=="+msgsize);
			// 校验报文长度
			if(length!=msgsize+6) {
				System.out.println("报文不合3");
				return;
			}
			
			// 报文类型
			String type = ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[4])).toUpperCase()) + ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[5])).toUpperCase());
			if(!"48A1".equals(type)) {
				System.out.println("报文不合法4");
				return;
			}
			
			// CRC16校验
			int crcReq = ByteUtil.cal_crc(buf, 12);
			int crcvalReq = Integer.parseInt(ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[12])).toUpperCase()) + ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[13])).toUpperCase()), 16);
			if(crcReq!=crcvalReq) {
				System.out.println("CRC校验失败，" + crcReq + " " + crcvalReq);
				return;
			}
			
			String panId = ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[8])).toUpperCase()) + ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[9])).toUpperCase());
			
			String deviceId = ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[10])).toUpperCase()) + ByteUtil.hexStringFormat(Integer.toHexString(ByteUtil.getUnsignedByte(buf[11])).toUpperCase());
			
			System.out.println("长度 >"+msgsize);
			
			// 解析签到报文
			byte[] rspByteArr = new byte[25];
			rspByteArr[0] = buf[0];
			rspByteArr[1] = buf[1];
			rspByteArr[2] = Long.valueOf(0x00).byteValue();
			rspByteArr[3] = Long.valueOf(0x13).byteValue();
			rspByteArr[4] = Long.valueOf(0x48).byteValue();
			rspByteArr[5] = Long.valueOf(0xB1).byteValue();
			
			rspByteArr[6] = buf[6];
			rspByteArr[7] = buf[7];
			
			rspByteArr[8] = buf[8];
			rspByteArr[9] = buf[9];
			
			rspByteArr[10] = buf[10];
			rspByteArr[11] = buf[11];
			
			// 结果码
			rspByteArr[12] = Long.valueOf(0x00).byteValue();
			rspByteArr[13] = Long.valueOf(0x00).byteValue();
			
			// 当前时间
			// 17年2月星期2，21号20点53分12秒
			// 17020221205312
			// 这样表示的话就是11 02 02……
			byte[] dateBytes = ByteUtil.getSysdateBytes();
			rspByteArr[14] = dateBytes[0];
			rspByteArr[15] = dateBytes[1];
			rspByteArr[16] = dateBytes[2];
			rspByteArr[17] = dateBytes[3];
			rspByteArr[18] = dateBytes[4];
			rspByteArr[19] = dateBytes[5];
			rspByteArr[20] = dateBytes[6];
					
			// CRS16
			int crcval = ByteUtil.cal_crc(rspByteArr, 21);
			rspByteArr[21] = Long.valueOf(crcval/256).byteValue();
			rspByteArr[22] = Long.valueOf(crcval%256).byteValue();
			
			// 结束符
			rspByteArr[23] = buf[14];
			rspByteArr[24] = buf[15];
			
			// 发送签到响应报文
			out.write(rspByteArr);
			out.flush();
			
			if(!"0000".equals(deviceId)) {
				System.out.println("deviceId==>" + deviceId);
				panId += "_" + deviceId;
			}
			
			SocketContainer oldContainer = NetController.getSocketPool().get(panId);
			if(oldContainer!=null) {
				oldContainer.stopThread();
				oldContainer.closeSocket();
			}
			
			SocketContainer container = new SocketContainer(panId,socket);
			container.start();
			
			NetController.getSocketPool().put(panId, container);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	 }
	
}
